package com.leyou.order.service;

import com.leyou.auth.pojo.UserInfo;
import com.leyou.common.dto.CartDTO;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.IdWorker;
import com.leyou.item.pojo.Sku;
import com.leyou.order.client.AddressClient;
import com.leyou.order.client.GoodsClient;
import com.leyou.order.dto.AddressDTO;
import com.leyou.order.dto.OrderDTO;
import com.leyou.order.interceptor.UserInterceptor;
import com.leyou.order.mapper.OrderDetailMapper;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.mapper.OrderStatusMapper;
import com.leyou.order.pojo.Order;
import com.leyou.order.pojo.OrderDetail;
import com.leyou.order.pojo.OrderStatus;
import com.leyou.order.util.OrderStatusEnum;
import com.leyou.order.util.PayHelper;
import com.leyou.order.util.PayStateEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderDetailMapper detailMapper;

    @Resource
    private OrderStatusMapper statusMapper;

    @Resource
    private IdWorker idWorker;

    @Resource
    private GoodsClient goodsClient;

    @Autowired
    private PayHelper payHelper;

    @Transactional
    public Long createOrder(OrderDTO orderDTO) {
        // 新增订单
        Order order = new Order();
        //   订单编号，基本信息
        long orderId = idWorker.nextId();
        order.setOrderId(orderId);
        order.setCreateTime(new Date());
        order.setPaymentType(orderDTO.getPaymentType());

        //   用户信息
        UserInfo user = UserInterceptor.getUserInfo();
        order.setUserId(user.getId());
        order.setBuyerNick(user.getUsername());
        order.setBuyerRate(false);

        //   收货人地址
        AddressDTO addr = AddressClient.queryAddressById(orderDTO.getAddressId());
        assert addr != null;
        order.setReceiver(addr.getName());
        order.setReceiverAddress(addr.getAddress());
        order.setReceiverCity(addr.getCity());
        order.setReceiverDistrict(addr.getDistrict());
        order.setReceiverMobile(addr.getPhone());
        order.setReceiverState(addr.getState());
        order.setReceiverZip(addr.getZipCode());

        //   金额
        Map<Long, Integer> cartMap = orderDTO.getCarts().stream()
                .collect(Collectors.toMap(CartDTO::getSkuId, CartDTO::getNum));
        List<Long> ids = new ArrayList<>(cartMap.keySet());
        List<Sku> skuList = goodsClient.querySkuByIds(ids);
        //   准备 OrderDetail 集合
        List<OrderDetail> detailList = new ArrayList<>();

        long totalPay = 0L;
        for (Sku sku : skuList) {
            totalPay += sku.getPrice() * cartMap.get(sku.getId());

            // 封装详情信息
            OrderDetail detail = new OrderDetail();
            detail.setImage(StringUtils.substringBefore(sku.getImages(), ","));
            detail.setNum(cartMap.get(sku.getId()));
            detail.setOrderId(orderId);
            detail.setOwnSpec(sku.getOwnSpec());
            detail.setPrice(sku.getPrice());
            detail.setSkuId(sku.getId());
            detail.setTitle(sku.getTitle());

            detailList.add(detail);
        }
        //   总金额
        order.setTotalPay(totalPay);
        //   实际金额
        order.setActualPay(totalPay + order.getPostFee());

        //   订单信息保存至数据库
        int count = orderMapper.insertSelective(order);
        if (count != 1) {
            log.error("[创建订单(1)] 创建订单失败，orderId：{}", orderId);
            throw new LyException(ExceptionEnum.CREATE_ORDER_ERROR);
        }

        // 新增订单详情
        count = detailMapper.insertList(detailList);
        if (count == 0) {
            log.error("[创建订单(2)] 创建订单失败，orderId：{}", orderId);
            throw new LyException(ExceptionEnum.CREATE_ORDER_ERROR);
        }

        // 新增订单状态
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setCreateTime(order.getCreateTime());
        orderStatus.setOrderId(orderId);
        orderStatus.setStatus(OrderStatusEnum.UN_PAY.getCode());
        statusMapper.insertSelective(orderStatus);

        // 减库存
        goodsClient.decreaseStock(orderDTO.getCarts());

        return orderId;
    }

    public Order queryOrderById(Long orderId) {
        // 查询订单
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order == null) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }

        // 查询订单详情
        OrderDetail detail = new OrderDetail();
        detail.setOrderId(orderId);
        List<OrderDetail> details = detailMapper.select(detail);
        if (CollectionUtils.isEmpty(details)) {
            throw new LyException(ExceptionEnum.ORDER_DETAIL_NOT_FOUND);
        }

        // 查询订单状态
        OrderStatus status = statusMapper.selectByPrimaryKey(orderId);
        if (status == null) {
            throw new LyException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }

        // 数据封装
        order.setOrderDetails(details);
        order.setOrderStatus(status);

        return order;
    }

    public String createPayUrl(Long orderId) {
        // 查询订单
        Order order = queryOrderById(orderId);
        // 判断订单状态
        Integer status = order.getOrderStatus().getStatus();
        if (OrderStatusEnum.UN_PAY.getCode() != status) {
            throw new LyException(ExceptionEnum.ORDER_STATUS_ERROR);
        }

        // 支付金额
        Long actualPay = /*order.getActualPay()*/ 1L;
        // 商品描述
        OrderDetail detail = order.getOrderDetails().get(0);
        String desc = detail.getTitle();

        return payHelper.createOrder(orderId, actualPay, desc);
    }

    public void handleNotify(Map<String, String> result) {
        // 校验数据
        payHelper.isSuccess(result);

        // 校验签名
        payHelper.isValidSign(result);

        // 校验金额
        String totalFeeStr = result.get("total_fee");
        String tradeNo = result.get("out_trade_no");
        if (StringUtils.isEmpty(totalFeeStr) || StringUtils.isEmpty(tradeNo)) {
            throw new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
        }

        //   获取结果金额
        long totalFee = Long.parseLong(totalFeeStr);
        //   获取订单金额
        Long orderId = Long.valueOf(tradeNo);
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (totalFee != /*order.getActualPay()*/ 1) {
            throw new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
        }

        // 修改订单状态
        OrderStatus status = new OrderStatus();
        status.setStatus(OrderStatusEnum.PAYED.getCode());
        status.setOrderId(orderId);
        status.setPaymentTime(new Date());
        int count = statusMapper.updateByPrimaryKeySelective(status);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR);
        }

        log.info("[订单回调] 订单支付成功！订单编号：{}", orderId);
    }

    public PayStateEnum queryOrderState(Long orderId) {
        // 获取订单状态
        OrderStatus status = statusMapper.selectByPrimaryKey(orderId);
        if (status == null) {
            throw new LyException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }
        if (status.getStatus() != OrderStatusEnum.UN_PAY.getCode()) {
            // 支付成功
            return PayStateEnum.SUCCESS;
        }

        // 支付状态为 1，不一定未支付，从微信支付查询确认
        return payHelper.queryPayState(orderId);
    }
}
